module block_max_dect_03(
		//时钟&复位
		input	wire			resetb,
		
		//设置总线			
		input   wire            set_clk,
		input   wire            set_d_ok,
		input   wire    [23:0]  set_addr,
		input   wire    [7:0]   set_data,

		input   wire	[4:0]	lan_num,
		input   wire	[9:0]	l_block_addr,

		//显示信号输入
		input   wire			pclk,
		input	wire			vsin,
		input	wire			dsin,
		input	wire	[29:0]	din,
		
		//输出给背光
		output	reg				block_end,
		
		input	wire			max_rclk,
		input	wire	[8:0]	max_raddr,
		output	wire 	[9:0]	max_gray,
		output	wire 	[23:0]	sum_gray,
		output	wire 	[13:0]	sum_pixel,
		output	wire 	[143:0]	sub_pixel,

		//调试信号
		output  wire	[32:0]	tout
		);

//************************************************/
//					参数定义
//************************************************/

//************************************************/
//					信号定义
/*************************************************/
reg				hl_info_en, l_info_wen, h_info_wen, buf_w_req, buf_wen;
reg		[12:0]	l_info_addr, buf_waddr, buf_raddr;
reg		[8:0]	buf_addr;
reg		[11:0]	h_info_addr;
wire			l_info_rdata, h_info_rdata;
reg		[47:0]	max_buf_wdata;
reg		[143:0]	count_buf_wdata;
wire	[47:0]	max_buf_rdata;
wire	[143:0]	count_buf_rdata;

reg				vs, hs, hs_a, hs_b;
reg				h_end_flag, h_end_flag_a, first_h, h_start_flag;
reg		[9:0]	r_data, g_data, b_data;

reg				l_end_flag, l_end_flag_a, l_end_flag_b, l_start_flag, l_start_flag_a;
reg		[9:0]	addr_base, buf_raddr_a, buf_raddr_b;
reg		[9:0]	b_data_a, rg_max, rgb_max, max_gray_b, max_gray_a, max_gray_h, max_gray_buf;
reg		[23:0]	sum_gray_b, sum_gray_a, sum_gray_h, sum_gray_buf;
reg		[15:0]	light_add;
reg		[8:0]	pixel_count, sub0_count, sub1_count, sub2_count, sub3_count, sub4_count, sub5_count, sub6_count, sub7_count;
reg		[8:0]	sub8_count, sub9_count, sub10_count, sub11_count, sub12_count, sub13_count, sub14_count, sub15_count;
reg		[9:0]	sub0_count_h, sub1_count_h, sub2_count_h, sub3_count_h, sub4_count_h, sub5_count_h, sub6_count_h, sub7_count_h;
reg		[9:0]	sub8_count_h, sub9_count_h, sub10_count_h, sub11_count_h, sub12_count_h, sub13_count_h, sub14_count_h, sub15_count_h;
reg		[8:0]	sub0_count_buf, sub1_count_buf, sub2_count_buf, sub3_count_buf, sub4_count_buf, sub5_count_buf, sub6_count_buf, sub7_count_buf;
reg		[8:0]	sub8_count_buf, sub9_count_buf, sub10_count_buf, sub11_count_buf, sub12_count_buf, sub13_count_buf, sub14_count_buf, sub15_count_buf;
reg		[13:0]	sum_pixel_h, sum_pixel_buf;

reg     [16:0]  info_addr;
reg     [7:0]   info_data;

//************************************************/
//					分区位置缓冲
//************************************************/	
//列分区位置缓冲  l_locate_map
swsr_1kw8_8kr1_sdp l_info_buf(
	.clka	(set_clk),
	.ena	(1'b1),
	.wea	(l_info_wen),
	.addra	(info_addr[9:0]),
	.dina	(info_data),
	
	.clkb	(pclk),
	.enb	(1'b1),
	.addrb	(l_info_addr),
	.doutb	(l_info_rdata)
	);

//行分区位置缓冲 h_locate_map
swsr_512w8_4kr1_sdp h_info_buf(
	.clka	(set_clk),
	.ena	(1'b1),
	.wea	(h_info_wen),
	.addra	(info_addr[8:0]),
	.dina	(info_data),
	
	.clkb	(pclk),
	.enb	(1'b1),
	.addrb	(h_info_addr),
	.doutb	(h_info_rdata)
	);

//*************************************************/
//		统计缓冲
//*************************************************/	
//求和/平均缓冲
/*
swsr_512x48_tdp max_buf(
	.clock_a(pclk),
	.address_a(buf_addr),
	.wren_a(buf_wen),
	.data_a(max_buf_wdata),
	.q_a(max_buf_rdata),
	
	.clock_b(max_rclk),
	.address_b(max_raddr),
	.wren_b(1'b0),
	.data_b(48'h0),
	.q_b({sum_gray, sum_pixel, max_gray})
);
*/

swsr_512x48_tdp max_buf (
  .clka(pclk),    // input wire clka
  .ena(1'b1),      // input wire ena
  .wea(buf_wen),      // input wire [0 : 0] wea
  .addra(buf_addr),  // input wire [8 : 0] addra
  .dina(max_buf_wdata),    // input wire [47 : 0] dina
  .douta(max_buf_rdata),  // output wire [47 : 0] douta
  .clkb(max_rclk),    // input wire clkb
  .enb(1'b1),      // input wire enb
  .web(1'b0),      // input wire [0 : 0] web
  .addrb(max_raddr),  // input wire [8 : 0] addrb
  .dinb(48'h0),    // input wire [47 : 0] dinb
  .doutb({sum_gray, sum_pixel, max_gray})  // output wire [47 : 0] doutb
);
/*
swsr_512x144_tdp count_buf(
	.clock_a(pclk),
	.address_a(buf_addr),
	.wren_a(buf_wen),
	.data_a(count_buf_wdata),
	.q_a(count_buf_rdata),
	
	.clock_b(max_rclk),
	.address_b(max_raddr),
	.wren_b(1'b0),
	.data_b(144'h0),
	.q_b(sub_pixel)
);
*/

swsr_512x144_tdp count_buf (
  .clka(pclk),    // input wire clka
  .ena(1'b1),      // input wire ena
  .wea(buf_wen),      // input wire [0 : 0] wea
  .addra(buf_addr),  // input wire [8 : 0] addra
  .dina(count_buf_wdata),    // input wire [143 : 0] dina
  .douta(count_buf_rdata),  // output wire [143 : 0] douta
  .clkb(max_rclk),    // input wire clkb
  .enb(1'b1),      // input wire enb
  .web(1'b0),      // input wire [0 : 0] web
  .addrb(max_raddr),  // input wire [8 : 0] addrb
  .dinb(144'h0),    // input wire [143 : 0] dinb
  .doutb(sub_pixel)  // output wire [143 : 0] doutb
);

//************************************************/
//		设置控制
//************************************************/	
always@(posedge set_clk) begin
	if (set_addr[23:16] == 8'h01)
		hl_info_en <= 1;
	else
		hl_info_en <= 0;
end
always@(posedge set_clk) begin
		info_addr <= set_addr[16:0];
end
always@(posedge set_clk) begin
		info_data <= set_data;
end

always@(posedge set_clk) begin
	if ((hl_info_en == 1) && (set_d_ok == 1) && (lan_num == set_addr[15:10]))
        l_info_wen <= 1;
    else
	    l_info_wen <= 0;          
end
		 
always@(posedge set_clk) begin
	if ((hl_info_en == 1) && (set_addr[15:10] == 8'b100000) && (set_d_ok == 1))
		h_info_wen <= 1;
	else
		h_info_wen <= 0;
end
		 
//************************************************/
//		信号缓冲
//************************************************/
always@(posedge pclk) begin
	vs <= vsin;
	hs <= dsin;
	r_data <= din[9:0];
	g_data <= din[19:10];
	b_data <= din[29:20];
end

//延时
always@(posedge pclk) begin
	hs_a <= hs;
	hs_b <= hs_a;
end

//************************************************/
//		行时序控制
//************************************************/
//列查询表地址
always@(posedge pclk)
	if (vs == 1)
		h_info_addr <= 0;
	else if ((hs_b == 1) && (hs_a == 0))
		h_info_addr <= h_info_addr + 1;
		
//行分区结束标志
always@(posedge pclk)
	if ((hs == 1) && (hs_a == 0))
		h_end_flag <= h_info_rdata;
	
//行分区最后一行标志
always@(posedge pclk)
	if ((hs == 1) && (hs_a == 0))
		block_end <= h_info_rdata;
	else if (hs_a == 0)
		block_end <= 0;
	
//每帧第一行标志
always@(posedge pclk)
	if (vs == 1)
		first_h <= 1;
	else if ((hs_b == 1) && (hs_a == 0))
		first_h <= 0;

//行分区结束标志延迟
always@(posedge pclk)
	if (vs == 1)
		h_end_flag_a <= 0;
	else if ((hs_b == 1) && (hs_a == 0))
		h_end_flag_a <= h_end_flag;

//行分区起始标志
always@(posedge pclk )
	if ((hs == 1) && (hs_a == 0)) begin
		if ((first_h == 1) || (h_end_flag_a == 1))
			h_start_flag <= 1;
		else
			h_start_flag <= 0;
		end
	
//行分区起始地址
always@(posedge pclk)
	if (vs == 1)
		addr_base <= 0;
	else if ((hs_b == 1) && (hs_a == 0) && (h_end_flag == 1))
		addr_base <= addr_base + l_block_addr;

//************************************************/
//		列时序控制
//************************************************/
//列查询表地址
always@(posedge pclk)
	if (hs == 0)
		l_info_addr <= 0;
	else
		l_info_addr <= l_info_addr + 1;
//列分区结束标志
always@(posedge pclk)
	if (hs_a == 0)
		l_end_flag <= 0;
	else
		l_end_flag <= l_info_rdata;
//列分区起始标志
always@(posedge pclk)
	if (hs_a == 0)
		l_start_flag <= 0;
	else if (hs_b == 0)
		l_start_flag <= 1;
	else if (l_end_flag == 1)
		l_start_flag <= 1;
	else
		l_start_flag <= 0;
		
//列分区结束标志延时
always@(posedge pclk) begin
	l_start_flag_a <= l_start_flag;
	l_end_flag_a <= l_end_flag;
	l_end_flag_b <= l_end_flag_a;
end
	
//数据缓冲读地址
always@(posedge pclk)
	if (hs_b == 0)
		buf_raddr <= addr_base;
    else if (l_end_flag == 1)
		buf_raddr <= buf_raddr + 1;
	
//数据缓冲读地址延时
always@(posedge pclk) begin
	buf_raddr_a <= buf_raddr;
	buf_raddr_b <= buf_raddr_a;
end

//数据缓冲写地址
always@(posedge pclk)
	if (l_end_flag_b == 1)
		buf_waddr <= buf_raddr_b;

//数据缓冲写请求
always@(posedge pclk)
	if (l_end_flag_b == 1)
		buf_w_req <= 1;
	else if (l_start_flag == 0)
		buf_w_req <= 0;
	
//数据缓冲地址
always @( * )
	if ((buf_w_req == 1) && (l_start_flag == 0))
		buf_wen <= 1;
	else
		buf_wen <= 0;
			
//数据缓冲地址
always @( * )
	if (buf_wen == 1)
		buf_addr <= buf_waddr;
	else
		buf_addr <= buf_raddr;
			
//************************************************/
//		数据处理
//************************************************/
//延时
always@(posedge pclk)
	b_data_a <= b_data;

//rg比较
always@(posedge pclk)
	if (r_data > g_data)
		rg_max <= r_data;
	else
		rg_max <= g_data;

//rgb比较
always@(posedge pclk)
	if (rg_max > b_data_a)
		rgb_max <= rg_max;
	else
		rgb_max <= b_data_a;

//一行内分区比较
always@(posedge pclk)
	if (l_start_flag == 1)
		max_gray_b <= rgb_max;
	else if (rgb_max > max_gray_b)
		max_gray_b <= rgb_max;

//一行内分区求和
always@(posedge pclk)
	if (l_start_flag == 1)
		sum_gray_b <= rgb_max;
	else
		sum_gray_b <= sum_gray_b + rgb_max;

//求和、比较延时
always@(posedge pclk) begin
	max_gray_a <= max_gray_b;
	sum_gray_a <= sum_gray_b;
end

//像素亮度分区
always@(posedge pclk)
	case (rgb_max[9:6])
		0:	light_add <= 16'h0001;
		1:	light_add <= 16'h0002;
		2:	light_add <= 16'h0004;
		3:	light_add <= 16'h0008;
		4:	light_add <= 16'h0010;
		5:	light_add <= 16'h0020;
		6:	light_add <= 16'h0040;
		7:	light_add <= 16'h0080;
		8:	light_add <= 16'h0100;
		9:	light_add <= 16'h0200;
		10:	light_add <= 16'h0400;
		11:	light_add <= 16'h0800;
		12:	light_add <= 16'h1000;
		13:	light_add <= 16'h2000;
		14:	light_add <= 16'h4000;
		15:	light_add <= 16'h8000;
	endcase

//亮度分布统计
always @(posedge pclk)
	if (l_start_flag_a == 1) begin
		pixel_count  <= 1;
		sub0_count <= light_add[0];
		sub1_count <= light_add[1];
		sub2_count <= light_add[2];
		sub3_count <= light_add[3];
		sub4_count <= light_add[4];
		sub5_count <= light_add[5];
		sub6_count <= light_add[6];
		sub7_count <= light_add[7];
		sub8_count <= light_add[8];
		sub9_count <= light_add[9];
		sub10_count <= light_add[10];
		sub11_count <= light_add[11];
		sub12_count <= light_add[12];
		sub13_count <= light_add[13];
		sub14_count <= light_add[14];
		sub15_count <= light_add[15];
		end
	else begin
		pixel_count  <= pixel_count + 1;
		sub0_count <= sub0_count + light_add[0];
		sub1_count <= sub1_count + light_add[1];
		sub2_count <= sub2_count + light_add[2];
		sub3_count <= sub3_count + light_add[3];
		sub4_count <= sub4_count + light_add[4];
		sub5_count <= sub5_count + light_add[5];
		sub6_count <= sub6_count + light_add[6];
		sub7_count <= sub7_count + light_add[7];
		sub8_count <= sub8_count + light_add[8];
		sub9_count <= sub9_count + light_add[9];
		sub10_count <= sub10_count + light_add[10];
		sub11_count <= sub11_count + light_add[11];
		sub12_count <= sub12_count + light_add[12];
		sub13_count <= sub13_count + light_add[13];
		sub14_count <= sub14_count + light_add[14];
		sub15_count <= sub15_count + light_add[15];
		end

//跨行分区比较
always@(posedge pclk)
	if (l_end_flag_b == 1) begin				//列结束时
		if (h_start_flag == 1)					//第一行直接保存统计数据
			max_gray_h <= max_gray_a;
		else if (max_gray_a > max_gray_buf)	//其他行和之前数据比较
			max_gray_h <= max_gray_a;
		else		
			max_gray_h <= max_gray_buf;
		end

//跨行分区求和
always@(posedge pclk)
	if (l_end_flag_b == 1) begin				//列结束时
		if (h_start_flag == 1)					//第一行直接保存统计数据
			sum_gray_h <= sum_gray_a;
		else									//其他行和之前数据累加
			sum_gray_h <= sum_gray_buf + sum_gray_a;
		end

//跨行亮度分布统计
always @(posedge pclk)
	if (l_end_flag_b == 1) begin				//列结束时
		if (h_start_flag == 1) begin			//第一行直接保存统计数据
			sum_pixel_h  <= pixel_count;
			sub0_count_h <= sub0_count;
			sub1_count_h <= sub1_count;
			sub2_count_h <= sub2_count;
			sub3_count_h <= sub3_count;
			sub4_count_h <= sub4_count;
			sub5_count_h <= sub5_count;
			sub6_count_h <= sub6_count;
			sub7_count_h <= sub7_count;
			sub8_count_h <= sub8_count;
			sub9_count_h <= sub9_count;
			sub10_count_h <= sub10_count;
			sub11_count_h <= sub11_count;
			sub12_count_h <= sub12_count;
			sub13_count_h <= sub13_count;
			sub14_count_h <= sub14_count;
			sub15_count_h <= sub15_count;
			end
		else begin								//其他行和之前数据累加
			sum_pixel_h  <= sum_pixel_buf  + pixel_count;
			sub0_count_h <= sub0_count_buf + sub0_count;
			sub1_count_h <= sub1_count_buf + sub1_count;
			sub2_count_h <= sub2_count_buf + sub2_count;
			sub3_count_h <= sub3_count_buf + sub3_count;
			sub4_count_h <= sub4_count_buf + sub4_count;
			sub5_count_h <= sub5_count_buf + sub5_count;
			sub6_count_h <= sub6_count_buf + sub6_count;
			sub7_count_h <= sub7_count_buf + sub7_count;
			sub8_count_h <= sub8_count_buf + sub8_count;
			sub9_count_h <= sub9_count_buf + sub9_count;
			sub10_count_h <= sub10_count_buf + sub10_count;
			sub11_count_h <= sub11_count_buf + sub11_count;
			sub12_count_h <= sub12_count_buf + sub12_count;
			sub13_count_h <= sub13_count_buf + sub13_count;
			sub14_count_h <= sub14_count_buf + sub14_count;
			sub15_count_h <= sub15_count_buf + sub15_count;
			end
		end

//************************************************/
//		数据映射
//************************************************/
//读映射
always@(posedge pclk)
	if (l_start_flag_a == 1) begin
		max_gray_buf	<= max_buf_rdata[9:0];
		sum_pixel_buf	<= max_buf_rdata[23:10];
		sum_gray_buf	<= max_buf_rdata[47:24];
		sub0_count_buf	<= count_buf_rdata[8:0];
		sub1_count_buf	<= count_buf_rdata[17:9];
		sub2_count_buf	<= count_buf_rdata[26:18];
		sub3_count_buf	<= count_buf_rdata[35:27];
		sub4_count_buf	<= count_buf_rdata[53:36];
		sub5_count_buf	<= count_buf_rdata[53:36];
		sub6_count_buf	<= count_buf_rdata[62:54];
		sub7_count_buf	<= count_buf_rdata[71:63];
		sub8_count_buf	<= count_buf_rdata[80:72];
		sub9_count_buf	<= count_buf_rdata[89:81];
		sub10_count_buf	<= count_buf_rdata[98:90];
		sub11_count_buf	<= count_buf_rdata[107:99];
		sub12_count_buf	<= count_buf_rdata[116:108];
		sub13_count_buf	<= count_buf_rdata[125:117];
		sub14_count_buf	<= count_buf_rdata[134:126];
		sub15_count_buf	<= count_buf_rdata[143:135];
		end

//写映射
always @( * ) begin
	max_buf_wdata[9:0]		= max_gray_h;
	max_buf_wdata[23:10]	= sum_pixel_h;
	max_buf_wdata[47:24]	= sum_gray_h;
	count_buf_wdata[7:0]	= sub0_count_h[7:0];
	count_buf_wdata[8]		= sub0_count_h[9] | sub0_count_h[8];
	count_buf_wdata[16:9]	= sub1_count_h[7:0];
	count_buf_wdata[17]		= sub1_count_h[9] | sub0_count_h[8];
	count_buf_wdata[25:18]	= sub2_count_h[7:0];
	count_buf_wdata[26]		= sub2_count_h[9] | sub0_count_h[8];
	count_buf_wdata[34:27]	= sub3_count_h[7:0];
	count_buf_wdata[35]		= sub3_count_h[9] | sub0_count_h[8];
	count_buf_wdata[43:36]	= sub4_count_h[7:0];                
	count_buf_wdata[44]		= sub4_count_h[9] | sub0_count_h[8];
	count_buf_wdata[52:45]	= sub5_count_h[7:0];                
	count_buf_wdata[53]		= sub5_count_h[9] | sub0_count_h[8];
	count_buf_wdata[61:54]	= sub6_count_h[7:0];                
	count_buf_wdata[62]		= sub6_count_h[9] | sub0_count_h[8];
	count_buf_wdata[70:63]	= sub7_count_h[7:0];                
	count_buf_wdata[71]		= sub7_count_h[9] | sub0_count_h[8];
	count_buf_wdata[79:72]	= sub8_count_h[7:0];
	count_buf_wdata[80]		= sub8_count_h[9] | sub0_count_h[8];
	count_buf_wdata[88:81]	= sub9_count_h[7:0];
	count_buf_wdata[89]		= sub9_count_h[9] | sub0_count_h[8];
	count_buf_wdata[97:90]	= sub10_count_h[7:0];                
	count_buf_wdata[98]		= sub10_count_h[9] | sub0_count_h[8];
	count_buf_wdata[106:99]	= sub11_count_h[7:0];                
	count_buf_wdata[107]	= sub11_count_h[9] | sub0_count_h[8];
	count_buf_wdata[115:108] = sub12_count_h[7:0];                
	count_buf_wdata[116] 	 = sub12_count_h[9] | sub0_count_h[8];
	count_buf_wdata[124:117] = sub13_count_h[7:0];                
	count_buf_wdata[125] 	 = sub13_count_h[9] | sub0_count_h[8];
	count_buf_wdata[133:126] = sub14_count_h[7:0];                
	count_buf_wdata[134] 	 = sub14_count_h[9] | sub0_count_h[8];
	count_buf_wdata[142:135] = sub15_count_h[7:0];                
	count_buf_wdata[143] 	 = sub15_count_h[9] | sub0_count_h[8];
	end

//************************************************/
//		调试信号
//************************************************/

assign	tout = {l_end_flag_b, max_gray_buf, max_gray_a, h_info_addr};
/*
ila_3 bldata (
	.clk(pclk), // input wire clk
	.probe0(l_end_flag), // input wire [0:0]  probe0  
	.probe1(l_info_rdata), // input wire [0:0]  probe1 
	.probe2(dsin), // input wire [0:0]  probe2 
	.probe3(l_info_addr[12:0]), // input wire [0:0]  probe2 
	.probe4(pixel_count[8:0]), // input wire [0:0]  probe0  
	.probe5(sum_pixel_h[13:0]), // input wire [0:0]  probe1 
	.probe6(sum_pixel_buf[13:0]), // input wire [0:0]  probe2 
	.probe7(l_end_flag_b), // input wire [0:0]  probe2
	.probe8(h_start_flag), // input wire [0:0]  probe1 
	.probe9(l_start_flag), // input wire [0:0]  probe2 
	.probe10(buf_addr[8:0]), // input wire [0:0]  probe2
	.probe11(buf_wen), // input wire [0:0]  probe2
	.probe12(max_buf_wdata[23:10]), // input wire [0:0]  probe2
	.probe13(max_buf_rdata[23:10]), // input wire [0:0]  probe1
	.probe14(h_end_flag_a), // input wire [0:0]  probe2
	.probe15(first_h), // input wire [0:0]  probe1 
	.probe16(h_end_flag) // input wire [0:0]  probe2 
    );*/
endmodule
